// $ANTLR 2.7.4: "langlexer.g" -> "AspectLanguageLexer.cs"$

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using antlr;
using antlr.collections.impl;
using TokenType = AspectSharp.Lang.TokenType;

public class AspectLanguageLexer : antlr.CharScanner, TokenStream
{

    private Dictionary<char, Action> MatchTable;
    private static readonly BitSet tokenSet_0_ = new BitSet(new long[] { 2305798500467610112L, 1729382249125642238L, 0L, 0L });
    private static readonly BitSet tokenSet_1_ = new BitSet(new long[] { 2305798483287740928L, 1729382249125642238L, 0L, 0L });

    public AspectLanguageLexer(Stream ins)
        : this(new ByteBuffer(ins))
    {
    }

    public AspectLanguageLexer(TextReader r)
        : this(new CharBuffer(r))
    {
    }

    public AspectLanguageLexer(InputBuffer ib)
        : this(new LexerSharedInputState(ib))
    {
    }

    public AspectLanguageLexer(LexerSharedInputState state)
        : base(state)
    {
        initialize();
    }
    private void initialize()
    {
        caseSensitiveLiterals = true;
        setCaseSensitive(true);
        literals = new Hashtable(100, (float)0.4, null, Comparer.Default);
        literals.Add("assignableFrom", 18);
        literals.Add("for", 5);
        literals.Add("method", 14);
        literals.Add("propertyread", 16);
        literals.Add("aspect", 4);
        literals.Add("interceptors", 11);
        literals.Add("end", 7);
        literals.Add("in", 6);
        literals.Add("advice", 12);
        literals.Add("customMatcher", 19);
        literals.Add("propertywrite", 17);
        literals.Add("pointcut", 13);
        literals.Add("include", 10);
        literals.Add("property", 15);
        literals.Add("import", 8);
        literals.Add("mixins", 9);
        literals.Add("includes", 21);
        literals.Add("excludes", 20);

        MatchTable = new Dictionary<char, Action>();
        MatchTable['*'] = () => Match('*', TokenType.ALL);
        MatchTable[':'] = () => Match(':', TokenType.COLON);
        MatchTable[';'] = () => Match(';', TokenType.SEMI);
        MatchTable[','] = () => Match(',', TokenType.COMMA);
        MatchTable['|'] = () => Match('|', TokenType.OR);
        MatchTable['<'] = () => Match('<', TokenType.INHERITS);
        MatchTable['['] = () => Match('[', TokenType.LBRACK);
        MatchTable[']'] = () => Match(']', TokenType.RBRACK);
        MatchTable['('] = () => Match('(', TokenType.LCURLY);
        MatchTable[')'] = () => Match(')', TokenType.RCURLY);
        MatchTable['.'] = () => Match('.', TokenType.DOT);
        MatchTable['/'] = () => mCOMMENT();
        MatchTable['\''] = () => mCHARLIT();
        MatchTable['"'] = () => mSTRING_LITERAL();
        MatchTable['\t'] = () => mWS();
        MatchTable['\n'] = () => mWS();
        MatchTable['\r'] = () => mWS();
        MatchTable['\u000c'] = () => mWS();
        MatchTable[' '] = () => mWS();

        for (char i = '0'; i <= '9'; i++) MatchTable[i] = () => mINTLIT();
        for (char c = 'a'; c <= 'z'; c++) MatchTable[c] = () => mID();
        for (char c = 'A'; c <= 'Z'; c++) MatchTable[c] = () => mID();
        MatchTable['_'] = () => mID();
    }

    private bool MatchByTable(char ch)
    {
        Action creator = null;
        if (!MatchTable.TryGetValue(ch, out creator))
            return false;

        creator();

        return true;
    }

    public override Token nextToken()
    {
        for (; ; )
        {
            try
            {
                try
                {
                    setCommitToPath(false);
                    resetText();

                    if (!MatchByTable(LA(1)))
                    {
                        if (LA(1) == EOF_CHAR)
                            MatchEOF();
                        else
                        {
                            consume();
                            continue;
                        }
                    }

                    if (returnToken_ == null)
                        continue;

                    return returnToken_;
                }
                catch (RecognitionException e)
                {
                    if (!getCommitToPath())
                    {
                        consume();
                        continue;
                    }
                    throw new TokenStreamRecognitionException(e);
                }
            }
            catch (CharStreamException cse)
            {
                if (cse is CharStreamIOException)
                    throw new TokenStreamIOException(((CharStreamIOException)cse).io);
                else
                    throw new TokenStreamException(cse.Message);
            }
        }
    }

    private void MatchEOF()
    {
        uponEOF();
        returnToken_ = makeToken(Token.EOF_TYPE);
    }

    private void Match(char ch, int tokenType)
    {
        var begin = text.Length;

        match(ch);
        returnToken_ = makeToken(tokenType);
        returnToken_.setText(text.ToString(begin, text.Length - begin));
    }

    private void mCOMMENT()
    {
        int _begin = text.Length;
        match("//");

        for (; ; )
        {
            if (!tokenSet_0_.member(LA(1)))
                break;
            match(tokenSet_0_);
        }

        returnToken_ = makeToken(Token.SKIP);
        returnToken_.setText(text.ToString(_begin, text.Length - _begin));
    }

    private void mINTLIT()
    {
        int _begin = text.Length;
        int flag = 0;

        for (; ; )
        {
            var ch = LA(1);
            if (ch >= '0' && ch <= '9')
            {
                matchRange('0', '9');
                flag++;
            }
            else if (flag >= 1)
                break;
            else
                throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());
        }

        returnToken_ = makeToken(TokenType.INTLIT);
        returnToken_.setText(text.ToString(_begin, text.Length - _begin));
    }

    private void mCHARLIT()
    {
        int _saveIndex = 0;
        int _begin = text.Length;

        _saveIndex = text.Length;
        match('\'');
        text.Length = _saveIndex;
        matchNot(TokenType.EOF/*_CHAR*/);
        _saveIndex = text.Length;
        match('\'');
        text.Length = _saveIndex;

        returnToken_ = makeToken(TokenType.CHARLIT);
        returnToken_.setText(text.ToString(_begin, text.Length - _begin));
    }

    private void mSTRING_LITERAL()
    {
        int _begin = text.Length;
        var _saveIndex = text.Length;

        match('"');
        text.Length = _saveIndex;

        for (; ; )
        {
            if ((LA(1) == '"') && (LA(2) == '"'))
            {
                match('"');
                _saveIndex = text.Length;
                match('"');
                text.Length = _saveIndex;
            }
            else if ((tokenSet_1_.member(LA(1))))
                match(tokenSet_1_);
            else
                break;
        }

        if ((LA(1) == '"'))
        {
            _saveIndex = text.Length;
            match('"');
            text.Length = _saveIndex;
        }

        returnToken_ = makeToken(TokenType.STRING_LITERAL);
        returnToken_.setText(text.ToString(_begin, text.Length - _begin));
    }

    private void mWS()
    {
        switch (LA(1))
        {
            case ' ':
                match(' ');
                break;
            case '\t':
                match('\t');
                break;
            case '\u000c':
                match('\f');
                break;
            case '\n':
            case '\r':
                if ((LA(1) == '\r') && (LA(2) == '\n'))
                    match("\r\n");
                else if (LA(1) == '\r') 
                    match('\r');
                else if ((LA(1) == '\n'))
                    match('\n');
                else
                    throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());
                newline();
                break;
            default:
                throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());
        }

        returnToken_ = null;
    }

    private void mID()
    {
        int _begin = text.Length;

        var ch = LA(1);
        if (ch >= 'a' && ch <= 'z')
            matchRange('a', 'z');
        else if (ch >= 'A' && ch <= 'Z')
            matchRange('A', 'Z');
        else if (ch == '_')
            match('_');
        else
            throw new NoViableAltForCharException((char)LA(1), getFilename(), getLine(), getColumn());

        for (; ; )
        {
            ch = LA(1);
            if (ch >= 'a' && ch <= 'z')
                matchRange('a', 'z');
            else if (ch >= 'A' && ch <= 'Z')
                matchRange('A', 'Z');
            else if (ch >= '0' && ch <= '9')
                matchRange('0', '9');
            else if (ch == '_')
                match('_');
            else break;
        }

        returnToken_ = makeToken(testLiteralsTable(TokenType.ID));
        returnToken_.setText(text.ToString(_begin, text.Length - _begin));
    }

  
}
